package ASintactico;
import java.io.*;
import Alexico.token;
/**
*los errores son los siguientes:
*<table style="border:1px"><tr><td>1</td><td>Comienzo de lexema invalido</td></tr><tr><td>2</td><td>Número mal formado</td></tr>
*       <tr><td>3</td><td>Char mal formado</td></tr><tr><td>4</td><td>String mal formado</td></tr>
*       <tr><td>5</td><td>Expresion Condicional mal formada. se esperaba un '&'</td><tr><tr><td>6</td><td>Operador relacional mal formado. se esperaba un '='</td></tr>
*       <tr><td>7</td><td>Identificador mal formado</td></tr><tr><td>8</td><td>Comentario mal formado</td></tr>
*       <tr><td>9</td><td>Expresion Condicional mal formada. se esperaba un '|'</td></tr>
*</table>
*/
public class customException extends Exception{
    
    final static String FinalizacionEjecucion = "Finalizacion del analisis";
    
    final static String ErrorSintactico = "Sintactico";
    final static String ErrorSemantico = "Semantico";
    final static String ErrorLexico = "Lexico";
    final static String ErrorEnEjecucion = "Error en tiempo de compilacion";
    final static String ErrorDelEntorno = "Ocurrio un error en el entorno";
    
    private final static String ErrorLectura = "Error al intenta leer el archivo fuente"; //archivo vacio
    final static int    ErrorLecturaCODE = 1;
    
    private final static String ArchivoFuenteVacio = "El archivo fuente es un archivo vacio"; //archivo vacio
    final static int    ArchivoFuenteVacioCODE = 2;
    
    private final static String ArchivoFuenteMalFormado = "Finalizacion erronea del Archivo fuente."; //Se esperaba el token $ de finalizacion de archivo y se encontro otro token.
    final static int    ArchivoFuenteMalFormadoCODE = 3;
    
    private final static String ExtendsSinTipo = "Definicion de herencia de clase erronea"; 
    final static int    ExtendsSinTipoCODE = 4;
    
    private final static String ClassDefSinLLaveCierra = "Bloque de definicion de clase sin cerrar"; 
    final static int    ClassDefSinLLaveCierraCODE = 5;
    
    private final static String ClassDefSinLLaveAbre = "Bloque de definicion de clase mal inicializado"; 
    final static int    ClassDefSinLLaveAbreCODE = 6;
    
    private final static String ClassDefIdentificador = "Bloque de definicion de clase sin Identificador"; 
    final static int    ClassDefIdentificadorCODE = 7;
    
    private final static String ConstMethodSeparador = "Luego de la definicion de un metodo/constructor se espera un seprador ';'"; 
    final static int    ConstMethodSeparadorCODE = 8;
    
    private final static String ConstMethod = "Se esperaba la construccion de un metodo o un constructor"; 
    final static int    ConstMethodCODE = 9;
    
    private final static String MethodDefIdentificador = "Bloque de definicion de metodo sin Identificador"; 
    final static int    MethodDefIdentificadorCODE = 10;
    
    private final static String ClassSinLLaveCierra = "Bloque de efectivizacion de clase sin cerrar"; 
    final static int    ClassSinLLaveCierraCODE = 11;
    
    private final static String ClassSinLLaveAbre = "Bloque de efectivizacion de clase mal inicializado"; 
    final static int    ClassSinLLaveAbreCODE = 12;
    
    private final static String ClassIdentificador = "Bloque de efectivizacion de clase sin Identificador"; 
    final static int    ClassIdentificadorCODE = 13;
    
    private final static String DeclaracionAtributosMetodos = "Error en la declaracion de atributos/metodos." + "\n              Se esperaba \",\" ,\";\" o \"(\" "; 
    final static int    DeclaracionAtributosMetodosCODE = 14;
    
    private final static String DeclaracionAtributos = "Se esperaba un identificador en la declaracion de atributos de clase"; 
    final static int    DeclaracionAtributosCODE = 15;
    
    private final static String DeclaracionListaAtributos = "Lista de atributos de clase mal formada." + "\n              Se esperaba \",\" o \";\" ";
    final static int    DeclaracionListaAtributosCODE = 16;
    
    private final static String DeclaracionNombreMetodo = "Se esperaba un identificador de metodo";
    final static int    DeclaracionNombreMetodoCODE = 17;
    
    private final static String comienzoParametrosMetodosConstructor = "Error en la construccion de metodos o constructores";
    final static int    comienzoParametrosMetodosConstructorCODE = 18;
    
    private final static String fieldConstMethod = "Atributo, metodo o constructor mal formado. " + "\n              Se esperaba un identificador o un \"(\"";
    final static int    fieldConstMethodCODE = 19;
    
    private final static String comientoFormalArgs = "Comienzo de lista de paramtros mal formada";
    final static int    comientoFormalArgsCODE = 20;
    
    private final static String finFormalArgs = "Lista de parametros sin parentesis que cierra";
    final static int    finFormalArgsCODE = 21;
    
    private final static String typeOrID = "Error de declaracion de tipo. Se esperaba un tipo primitivo o un identificador de clase";
    final static int    typeOrIDCODE = 22;
    
    private final static String identificadorFormaArg = "Error de declaracion de parametros formales. Se esperaba un identificador";
    final static int    identificadorFormaArgCODE = 23;

    private final static String declaracionTipo = "Error de declaracion de tipo:  no es un tipo valido";
    final static int    declaracionTipoCODE = 24;
    
    private final static String finBloque = "Bloque mal finalizado";
    final static int    finBloqueCODE = 25;
    
    private final static String comienzoBloque = "Bloque mal inicializado";
    final static int    comientzoBloqueCODE = 26;
    
    private final static String separadorSentencia = "Falta separador de sentencias";
    final static int    separadorSentenciaCODE = 27;
    
    private final static String sentencia = "Sentencia mal formada";
    final static int    sentenciaCODE = 28;
    
    private final static String sentenciaIFParentesisCierra = "Falta parentesis que cierra a la expresion condicional de sentencia IF";
    final static int    sentenciaIFParentesisCierraCODE = 29;
    
    private final static String sentenciaIFParentesisAbre = "Falta parentesis que abre a la expresion condicional de sentencia IF";
    final static int    sentenciaIFParentesisAbreCODE = 30;
    
    private final static String sentenciaIFsentencia = "Sentencia If mal formada: La sentencia no es una sentencia correcta";
    final static int    sentenciaIFsentenciaCODE = 31;
    
    private final static String sentenciaIFExpresion = "La exprecion condicional esta mal formada";
    final static int    sentenciaIFExpresionCODE = 32;
    
    private final static String sentenciaWhileParentesisAbre = "Falta parentesis que abre a la expresion condicional de sentencia While";
    final static int    sentenciaWhileParentesisAbreCODE = 33;
    
    private final static String sentenciaWhileParentesisCierra = "Falta parentesis que cierra a la expresion condicional de sentencia While";
    final static int    sentenciaWhileParentesisCierraCODE = 34;
    
    private final static String sentenciaForParentesisCierra = "Falta parentesis que cierra a la expresion condicional de sentencia For";
    final static int    sentenciaForParentesisCierraCODE = 35;
    
    private final static String sentenciaForParentesisAbre = "Falta parentesis que Abre a la expresion condicional de sentencia For";
    final static int    sentenciaForParentesisAbreCODE = 36;
    
    private final static String sentenciaForSeparador = "Falta \";\" como separador de expresiones en  sentencia For";
    final static int    sentenciaForSeparadorCODE = 37;
    
    private final static String expresionEnAsignacion = "Se esperaba una expresion en una sentencia de asignacion";
    final static int    expresionEnAsignacionCODE = 38;
    
    private final static String expresionParentisacion = "Parentisacion desvalanceada";
    final static int    expresionParentisacionCODE = 39;
    
    private final static String expresionNewNecesitaID = "Sentencia de creacion de objetos (new) necesita un identificador";
    final static int    expresionNewNecesitaIDCODE = 40;
    
    private final static String expresionSuperNecesitaID = "Sentencia super necesita un identificador";
    final static int    expresionSuperNecesitaIDCODE = 41;
    
    private final static String expresionSuperNecesitaPunto = "Se esperaba un \".\" luego de la palabra reservada super ";
    final static int    expresionSuperNecesitaPuntoCODE = 42;
    
    private final static String expresionMalFormada = "Expression Mal formada";
    final static int    expresionMalFormadaCODE = 43;
    
    private final static String identificadorNombreMetodo = "Se esperaba un identificador de nombre de metodo";
    final static int    identificadorNombreMetodoCODE = 44;
    
    private final static String literal = "Se esperaba un Literal";
    final static int    literalCODE = 45;
    
    private final static String paramActParentesisAbre = "Falta parentesis que Abre en la definicion de parametros actuales";
    final static int    paramActParentesisAbreCODE = 46;

    private final static String paramActParentesisCierra = "Falta parentesis que Cierra en la definicion de parametros actuales";
    final static int    paramActParentesisCierraCODE = 47;
    
    private static String obtenerTipoError(int nro){
        String tipo = "";
        if(nro <=2){
            tipo = customException.ErrorDelEntorno;
        }
        
        if(nro >= 3)//error de tipo Sintactico
            tipo = customException.ErrorSintactico;
        else{
        
        }
        return tipo;
    }
            
    
    private static String msgSegunError(int nro)
    {
        String msg="";
        switch (nro){
            case customException.ArchivoFuenteMalFormadoCODE:{
                msg = customException.ArchivoFuenteMalFormado;
                break;
            }
            case customException.ArchivoFuenteVacioCODE:{
                msg = customException.ArchivoFuenteVacio;
                break;
            }
            case customException.ErrorLecturaCODE:{
                msg = customException.ErrorLectura;
                break;
            }
            case customException.ExtendsSinTipoCODE:{
               msg = customException.ExtendsSinTipo;
               break;
            }
            case customException.ClassDefSinLLaveCierraCODE:{
               msg = customException.ClassDefSinLLaveCierra;
               break;
            }
            case customException.ClassDefSinLLaveAbreCODE:{
               msg = customException.ClassDefSinLLaveAbre;
               break;
            }
            case customException.ClassDefIdentificadorCODE:{
               msg = customException.ClassDefIdentificador;
               break;
            }
            case customException.ConstMethodSeparadorCODE:{
               msg = customException.ConstMethodSeparador;
               break;
            }
            case customException.ConstMethodCODE:{
               msg = customException.ConstMethod;
               break;
            }
            case customException.MethodDefIdentificadorCODE:{
               msg = customException.MethodDefIdentificador;
               break;
            }
            case customException.ClassSinLLaveCierraCODE:{
               msg = customException.ClassSinLLaveCierra;
               break;
            }
            case customException.ClassSinLLaveAbreCODE:{
               msg = customException.ClassSinLLaveAbre;
               break;
            }
            case customException.ClassIdentificadorCODE:{
               msg = customException.ClassIdentificador;
               break;
            }
            case customException.DeclaracionAtributosMetodosCODE:{
               msg = customException.DeclaracionAtributosMetodos;
               break;
            }
            case customException.DeclaracionAtributosCODE:{
               msg = customException.DeclaracionAtributos;
               break;
            }
            case customException.DeclaracionListaAtributosCODE:{
               msg = customException.DeclaracionListaAtributos;
               break;
            }
            case customException.DeclaracionNombreMetodoCODE:{
               msg = customException.DeclaracionNombreMetodo;
               break;
            }
            case customException.comienzoParametrosMetodosConstructorCODE:{
               msg = customException.comienzoParametrosMetodosConstructor;
               break;
            }
            case customException.fieldConstMethodCODE:{
               msg = customException.fieldConstMethod;
               break;
            }
            case customException.comientoFormalArgsCODE:{
               msg = customException.comientoFormalArgs;
               break;
            }
            case customException.finFormalArgsCODE:{
               msg = customException.finFormalArgs;
               break;
            }
            case customException.typeOrIDCODE:{
               msg = customException.typeOrID;
               break;
            }
            case customException.identificadorFormaArgCODE:{
               msg = customException.identificadorFormaArg;
               break;
            }
            case customException.declaracionTipoCODE:{
               msg = customException.declaracionTipo;
               break;
            }
            case customException.finBloqueCODE:{
               msg = customException.finBloque;
               break;
            }
            case customException.comientzoBloqueCODE:{
               msg = customException.comienzoBloque;
               break;
            }
            case customException.separadorSentenciaCODE:{
               msg = customException.separadorSentencia;
               break;
            }
            case customException.sentenciaCODE:{
               msg = customException.sentencia;
               break;
            }  
            case customException.sentenciaIFParentesisCierraCODE:{
               msg = customException.sentenciaIFParentesisCierra;
               break;
            }  
            case customException.sentenciaIFParentesisAbreCODE:{
               msg = customException.sentenciaIFParentesisAbre;
               break;
            }  
            case customException.sentenciaIFsentenciaCODE:{
               msg = customException.sentenciaIFsentencia;
               break;
            }
            case customException.sentenciaIFExpresionCODE:{
               msg = customException.sentenciaIFExpresion;
               break;
            }
            case customException.sentenciaWhileParentesisAbreCODE:{
               msg = customException.sentenciaWhileParentesisAbre;
               break;
            }
            case customException.sentenciaWhileParentesisCierraCODE:{
               msg = customException.sentenciaWhileParentesisCierra;
               break;
            }
            case customException.sentenciaForParentesisCierraCODE:{
               msg = customException.sentenciaForParentesisCierra;
               break;
            }
            case customException.sentenciaForParentesisAbreCODE:{
               msg = customException.sentenciaForParentesisAbre;
               break;
            }
            case customException.sentenciaForSeparadorCODE:{
               msg = customException.sentenciaForSeparador;
               break;
            }
            case customException.expresionEnAsignacionCODE:{
               msg = customException.expresionEnAsignacion;
               break;
            }
            case customException.expresionParentisacionCODE:{
               msg = customException.expresionParentisacion;
               break;
            }    
            case customException.expresionNewNecesitaIDCODE:{
               msg = customException.expresionNewNecesitaID;
               break;
            }
            case customException.expresionSuperNecesitaIDCODE:{
               msg = customException.expresionSuperNecesitaID;
               break;
            }
            case customException.expresionSuperNecesitaPuntoCODE:{
               msg = customException.expresionSuperNecesitaPunto;
               break;
            }
            case customException.expresionMalFormadaCODE:{
               msg = customException.expresionMalFormada;
               break;
            }
            case customException.identificadorNombreMetodoCODE:{
               msg = customException.identificadorNombreMetodo;
               break;
            }
            case customException.literalCODE:{
               msg = customException.literal;
               break;
            }
            case customException.paramActParentesisAbreCODE:{
               msg = customException.paramActParentesisAbre;
               break;
            }
            case customException.paramActParentesisCierraCODE:{
               msg = customException.paramActParentesisCierra;
               break;
            }
             
             

    
        }
        return msg;
    }
     private static String detalleSegunError(token t,int nro)
    {
        String msg="";
        switch (nro){
            case customException.ArchivoFuenteMalFormadoCODE:{
                msg="Se encontro " + t.getLexema() +
                    "\n NRO. LINEA: " + t.getNumLinea() +
                    "\n " + FinalizacionEjecucion    ;
             break;
            }
        }
        return msg;
    }
     
     private static String detalle(token t)
    {
        String msg="";
               msg="Se encontro " + t.getLexema() +
                    "\n NRO. LINEA: " + t.getNumLinea() +
                    "\n " + FinalizacionEjecucion    ;
        return msg;
    }
     
     private static String detalle(token tEsperado,token tActual)
    {   
        String token;
        if(tActual.getLexema().equals("$"))
        {
            token = "Fin de archivo";
        }
        else{
            token = tActual.getLexema();
        }
        String msg="";
               msg="Se esperaba " + "\"" + tEsperado.getLexema()+ "\"" + " y se encontro " + "\""+ token + "\"" +
                    "\n NRO. LINEA: " + tActual.getNumLinea() +
                    "\n " + FinalizacionEjecucion    ;
        return msg;
    }
     
    
     @Override
    public void printStackTrace(PrintStream ps) {
        System.out.println(getMessage());
    }
    
      
    public customException(int error , token tEcontrado)
    {
        super("\n\n OCURRIO UN ERROR durante analisis:" +
                "\n ---------------------------------- \n " +
                "\n TIPO: " + obtenerTipoError(error) +
                "\n INFORMACION: " + msgSegunError(error) +
                "\n DETALLE: " + detalle(tEcontrado));
    }
    
     public customException(int error , token tesperado,token tokenactual)
    {
        super("\n\n OCURRIO UN ERROR durante analisis:" +
                "\n ----------------------------------\n " +
                "\n TIPO: " + obtenerTipoError(error) +
                "\n INFORMACION: " + msgSegunError(error) +
                "\n DETALLE: " + detalle(tesperado,tokenactual));
    }
    
      public customException(int error)
    {
        super("\n\n OCURRIO UN ERROR durante analisis:" +
                "\n ---------------------------------- \n " +
                "\n TIPO: " + obtenerTipoError(error) +
                "\n INFORMACION: " + msgSegunError(error));
    }
     
     public static void construirError() {}
/**
*Crea una nueva instancia de ErrorLexico
*@param tipo
*/
    public customException(token tesperado,token tokenactual )
    {
         super("\n\n Error Sintactico:" +
                "\n ********************************************************************************************** \n " +
                " Se esperaba " + tesperado.getNombre() +
                " y se encontro " + tokenactual.getNombre() + " en la linea " + tokenactual.getNumLinea() +
                "\n ********************************************************************************************** \n");
    }
    public customException(String Error, token Encontrado ) {
        super("\n\n Error Sintactico:" +
                "\n ********************************************************************************************** \n " +
                "    " + Error +
                 " y se encontro " +Encontrado.getNombre() + " en la linea " + Encontrado.getNumLinea() +
                "\n ********************************************************************************************** \n");
    }
    public customException(String sms )
    {
         super("ERROR Sintactico =====>  " + sms);
    }
}
